package com.xcm.sso.server.controller;

import com.xcm.sso.server.constant.ResponseConstant;
import com.xcm.sso.server.model.JsonResponse;
import com.xcm.sso.server.model.Ticket;
import com.xcm.sso.server.util.DESUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 登录和注销控制器
 * 
 * @author sheefee
 * @date 2017年9月12日 下午2:09:47
 *
 */
@Controller
public class LoginController {

	/** 账户信息 */
	private static Map<String, String> accounts;

	/** 单点登录标记 */
	private static Map<String, Ticket> tickets;

	/** cookie名称 */
	private String cookieName = "XCIPSCOOKIECAFEBABE";

	/** 是否安全协议 */
	private boolean secure = false;

	/** 密钥 ticket内容加密密钥，必须为24个字符，中文算2个字符 */
//	private String secretKey = "!152CAFE973*BABE@SSOAUTH";
	private String secretKey = "!152CAFE973*BABE@SSOAUTH";

	/** ticket有效时间 */
	private static int ticketTimeout = 10080;

	/** 回收ticket线程池 */

	static {
		accounts = new HashMap<String, String>();
		accounts.put("zhangsan", "zhangsan");
		accounts.put("lisi", "lisi");
		accounts.put("wangwu", "wangwu");
		tickets = new ConcurrentHashMap<String, Ticket>();
	}

	/**
	 * 预登录
	 */
	@RequestMapping(value = "/preLogin")
	public String preLogin(HttpServletRequest request, HttpServletResponse response, Model model) throws IOException {
		Cookie ticket = null;
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (Cookie cookie: cookies) {
				if (cookie.getName().equals(cookieName)) {
					ticket = cookie;
					break;
				}
			}
		}
		//目的地址
		String gotoURL = request.getParameter("gotoURL");
		//设置cookie地址
		String setCookieURL = request.getParameter("setCookieURL");
		if (ticket == null) {
			model.addAttribute("gotoURL", gotoURL);
			model.addAttribute("setCookieURL", setCookieURL);
			return "login";
		} else {
			String encodedTicket = ticket.getValue();
			//解密
			String decodedTicket = DESUtils.decrypt(encodedTicket, secretKey);
			if (tickets.containsKey(decodedTicket)) {
				if (setCookieURL !=  null) {
					response.sendRedirect(setCookieURL + "?ticket=" + encodedTicket + "&expiry=" + ticket.getMaxAge() + "&gotoURL=" + gotoURL);
				}
			} else {
				model.addAttribute("gotoURL", gotoURL);
				model.addAttribute("setCookieURL", setCookieURL);
				return "login";
			}
		}
		model.addAttribute("gotoURL", gotoURL);
		model.addAttribute("setCookieURL", setCookieURL);
		return "login";
	}

	@ResponseBody
	@RequestMapping(value = "/authTicket")
	public Object authTicket(HttpServletRequest request) {
		String encodedTicket = request.getParameter("cookieName");
		if (encodedTicket == null) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "Ticket can not be empty!");
		} else {
			String decodedTicket = DESUtils.decrypt(encodedTicket, secretKey);
			if (tickets.containsKey(decodedTicket)) {
				return new JsonResponse(ResponseConstant.CODE_SUCCESS, "用戶信息");
			} else {
				return new JsonResponse(ResponseConstant.CODE_FAIL, "Ticket is not found!");
			}
		}
	}

	@ResponseBody
	@RequestMapping(value = "/logout")
	public Object doLogout(HttpServletRequest request) throws IOException {
		String encodedTicket = request.getParameter("cookieName");
		if(encodedTicket == null) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "Ticket can not be empty!");
		} else {
			String decodedTicket = DESUtils.decrypt(encodedTicket, secretKey);
			tickets.remove(decodedTicket);
			return new JsonResponse(ResponseConstant.CODE_SUCCESS, "成功注销");
		}
	}

	@RequestMapping(value = "/doLogin")
	public String doLogin(HttpServletRequest request, HttpServletResponse response, Model model) {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		String pass = accounts.get(username);
		//目的地址
		String gotoURL = request.getParameter("gotoURL");
		//设置cookie地址
		String setCookieURL = request.getParameter("setCookieURL");
		if (pass == null || !pass.equals(password)) {
			model.addAttribute("gotoURL", gotoURL);
			model.addAttribute("setCookieURL", setCookieURL);
			return "login";
		} else {
			String ticketKey = UUID.randomUUID().toString().replace("-", "");
			String encodedticketKey = DESUtils.encrypt(ticketKey, secretKey);
			Timestamp createTime = new Timestamp(System.currentTimeMillis());
			Calendar cal = Calendar.getInstance();
			cal.setTime(createTime);
			cal.add(Calendar.MINUTE, ticketTimeout);
			Timestamp recoverTime = new Timestamp(cal.getTimeInMillis());
			Ticket ticket = new Ticket(username, createTime, recoverTime);

			tickets.put(ticketKey, ticket);

			String[] checks = request.getParameterValues("autoAuth");
			int expiry = -1;
			if(checks != null && "1".equals(checks[0])) {
				expiry = 7 * 24 * 3600;
			}
			Cookie cookie = new Cookie(cookieName, encodedticketKey);
			// 为true时用于https
			cookie.setSecure(secure);
			cookie.setMaxAge(expiry);
			cookie.setPath("/");
			response.addCookie(cookie);

			String redirectURL = setCookieURL+"?gotoURL=" + gotoURL + "&ticket=" + encodedticketKey + "&expiry=" + expiry;
			return "redirect:" + redirectURL;
		}
	}
}